package com.example.sentinel.infrastructure.aspect;

import com.example.sentinel.infrastructure.handler.SentinelExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Aspect
@Component
@Slf4j
public class LogAspect {

    @Pointcut("@annotation(com.example.sentinel.infrastructure.annotation.SentinelLog)")
    public void pointcut(){}

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        long startTime = System.currentTimeMillis();
        String threadName = Thread.currentThread().getName();

        try {
            return joinPoint.proceed();
        } catch (Throwable ex) {
            throw ex;
        } finally {
            // 从ThreadLocal中获取限流和熔断状态
            SentinelExceptionHandler.BlockInfo blockInfo = SentinelExceptionHandler.getBlockInfo();
            boolean isFlowBlocked = blockInfo != null && blockInfo.isFlowBlocked();
            boolean isDegradeBlocked = blockInfo != null && blockInfo.isDegradeBlocked();

            // 耗时
            long costTime = System.currentTimeMillis() - startTime;
            String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(startTime));

            log.info("请求时间: {}, 线程名: {}, 耗时: {}ms, 限流: {}, 熔断: {}",
                    time, threadName, costTime, isFlowBlocked, isDegradeBlocked);

            // 移除ThreadLocal中的数据，避免内存泄漏
            SentinelExceptionHandler.removeBlockInfo();
        }
    }
}    